﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace ArcFaceDemo.ArcFace
{
    /// <summary>
    /// 年龄检测类
    /// </summary>
    public class FaceDllImport
    {


        /// <summary>
        /// 初始化脸部检测引擎
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="sdkKey"></param>
        /// <param name="pMem">分配给引擎使用的内存地址</param>
        /// <param name="lMemSize">分配给引擎使用的内存大小</param>
        /// <param name="pEngine">[out] 引擎 handl</param>
        /// <param name="iOrientPriority">期望的脸部检测角度的优先级</param>
        /// <param name="nScale">用于数值表示的最小人脸尺寸 有效值范围[2,50] 推荐值 16</param>
        /// <param name="nMaxFaceNum">用户期望引擎最多能检测出的人脸数 有效值范围[1,100]</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_face_detection.dll", EntryPoint = "AFD_FSDK_InitialFaceEngine", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFD_FSDK_InitialFaceEngine(string appId, string sdkKey, IntPtr pMem, int lMemSize, ref IntPtr pEngine, int iOrientPriority, int nScale, int nMaxFaceNum);

        /// <summary>
        /// 根据输入的图像检测出人脸位置，一般用于静态图像检测
        /// </summary>
        /// <param name="pEngine">引擎 handle</param>
        /// <param name="pImgData">带检测图像信息</param>
        /// <param name="pFaceRes">人脸检测结果</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_face_detection.dll", EntryPoint = "AFD_FSDK_StillImageFaceDetection", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFD_FSDK_StillImageFaceDetection(IntPtr pEngine, IntPtr pImgData, ref IntPtr pFaceRes);


        /// <summary>
        /// 销毁引擎，释放相应资源
        /// </summary>
        /// <param name="pEngine"></param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_face_detection.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int AFD_FSDK_UninitialFaceEngine(IntPtr pEngine);

        /// <summary>
        /// 获取 SDK 版本信息
        /// </summary>
        /// <param name="pEngine">引擎 handle</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_face_detection.dll", EntryPoint = "AFD_FSDK_GetVersion", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr AFD_FSDK_GetVersion(IntPtr pEngine);
        

        /// <summary>
        /// 初始化年龄检测引擎
        /// </summary>
        /// <param name="appId">用户申请 SDK 时获取的 App Id</param>
        /// <param name="sdkKey">用户申请 SDK 时获取的 SDK Key</param>
        /// <param name="pMem">分配给引擎使用的内存地址</param>
        /// <param name="lMemSize">分配给引擎使用的内存大小</param>
        /// <param name="phEngine">引擎 handle[out]</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_age_estimation.dll", EntryPoint = "ASAE_FSDK_InitAgeEngine", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ASAE_FSDK_InitAgeEngine(string appId, string sdkKey, IntPtr pMem, int lMemSize, ref IntPtr phEngine);


       

        /// <summary>
        /// 检测静态图片中人物的年龄
        /// </summary>
        /// <param name="pEngine">引擎 handle</param>
        /// <param name="pImginfo">输入的图像数据</param>
        /// <param name="pFaceRes">已检测到的脸部信息</param>
        /// <param name="pAgeRes">年龄检测结果[out]</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_age_estimation.dll", EntryPoint = "ASAE_FSDK_AgeEstimation_StaticImage", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ASAE_FSDK_AgeEstimation_StaticImage(IntPtr pEngine, IntPtr pImginfo, IntPtr pFaceRes, ref IntPtr pAgeRes);


        /// <summary>
        /// 检测动态视频中人物的年龄
        /// </summary>
        /// <param name="pEngine">引擎 handle</param>
        /// <param name="pImginfo">输入的图像数据</param>
        /// <param name="pFaceRes">已检测到的脸部信息,需要事先用人脸引擎检测出</param>
        /// <param name="pAgeRes">年龄检测结果[out]</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_age_estimation.dll", EntryPoint = "ASAE_FSDK_AgeEstimation_Preview", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ASAE_FSDK_AgeEstimation_Preview(IntPtr pEngine, IntPtr pImginfo, IntPtr pFaceRes, ref IntPtr pAgeRes);


        /// <summary>
        /// 销毁引擎,释放相应资源
        /// </summary>
        /// <param name="pEngine">引擎 handle</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_age_estimation.dll", EntryPoint = "ASAE_FSDK_UninitAgeEngine", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ASAE_FSDK_UninitAgeEngine(IntPtr pEngine);

        /// <summary>
        /// 获取 SDK 版本信息
        /// </summary>
        /// <param name="pEngine">引擎 handle</param>
        /// <returns></returns>
        [DllImport("libarcsoft_fsdk_age_estimation.dll", EntryPoint = "ASAE_FSDK_GetVersion", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr ASAE_FSDK_GetVersion(IntPtr pEngine);
    }




    public struct MRECT
    {

        public int left;

        public int top;

        public int right;

        public int bottom;
    }


//    typedef struct {
//        MInt32 nFace;                     // number of faces detected
//    MRECT* rcFace;                    // The bounding box of face
//    AFD_FSDK_OrientCode* lfaceOrient; // the angle of each face
//}
//AFD_FSDK_FACERES, * LPAFD_FSDK_FACERES;
/// <summary>
/// 检测到的脸部信息 与帮助文档不一致 注意
/// </summary>
public struct AFD_FSDK_FACERES
    {
        /// <summary>
        /// 人脸个数 long
        /// </summary>
        public int nFace;

        /// <summary>
        ///  MRECT* 人脸框信息数组
        /// </summary>
        public System.IntPtr rcFace;

        /// <summary>
        /// 人脸角度信息 AFD_FSDK_OrientCode
        /// </summary>
        public System.IntPtr lfaceOrient;
    }

    //定义FD的版本号
    public struct AFD_FSDK_Version
    {
        public int lCodebase;
        public int lMajor;
        public int lMinor;
        public int lBuild;
        public IntPtr Version;
        public IntPtr BuildDate;
        public IntPtr CopyRight;
    }

    /// <summary>
    /// 定义脸部检测角度的优先级
    /// </summary>
    public enum AFD_FSDK_OrientPriority
    {
        AFD_FSDK_OPF_0_ONLY = 1,
        AFD_FSDK_OPF_90_ONLY = 2,
        AFD_FSDK_OPF_270_ONLY = 3,
        AFD_FSDK_OPF_180_ONLY = 4,
        AFD_FSDK_OPF_0_HIGHER_EXT = 5
    }


    /// <summary>
    /// 定义检测结果中的人脸角度
    /// </summary>
    public enum AFD_FSDK_OrientCode
    {
        AFD_FSDK_FOC_0 = 1,
        AFD_FSDK_FOC_90 = 2,
        AFD_FSDK_FOC_270 = 3,
        AFD_FSDK_FOC_180 = 4,
        AFD_FSDK_FOC_30 = 5,
        AFD_FSDK_FOC_60 = 6,
        AFD_FSDK_FOC_120 = 7,
        AFD_FSDK_FOC_150 = 8,
        AFD_FSDK_FOC_210 = 9,
        AFD_FSDK_FOC_240 = 10,
        AFD_FSDK_FOC_300 = 11,
        AFD_FSDK_FOC_330 = 12
    }

    public struct ASVLOFFSCREEN
    {
        public int u32PixelArrayFormat;
        public int i32Width;
        public int i32Height;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.SysUInt)]
        public System.IntPtr[] ppu8Plane;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)]
        public int[] pi32Pitch;
    }


    /// <summary>
    /// 定义基于逆时针方向的人脸角度
    /// </summary>
    enum ASAE_FSDK_AgeOrientCode
    {
        ASAE_FSDK_FOC_Age_0 = 1,
        ASAE_FSDK_FOC_Age_90 = 2,
        ASAE_FSDK_FOC_Age_270 = 3,
        ASAE_FSDK_FOC_Age_180 = 4,
        ASAE_FSDK_FOC_Age_30 = 5,
        ASAE_FSDK_FOC_Age_60 = 6,
        ASAE_FSDK_FOC_Age_120 = 7,
        ASAE_FSDK_FOC_Age_150 = 8,
        ASAE_FSDK_FOC_Age_210 = 9,
        ASAE_FSDK_FOC_Age_240 = 10,
        ASAE_FSDK_FOC_Age_300 = 11,
        ASAE_FSDK_FOC_Age_330 = 12
    };

    public struct ASAE_FSDK_AGERESULT
    {
        /// <summary>
        ///  MRECT* 人脸框信息数组
        /// </summary>
        public System.IntPtr pFaceRectArray;

        /// <summary>
        /// 输入的人脸角度数组 int
        /// </summary>
        public System.IntPtr pFaceOrientArray;

        /// <summary>
        /// 人脸个数
        /// </summary>
        public int lFaceNumber;
    }
    /// <summary>
    /// SDK 版本信息
    /// </summary>
    public struct ASAE_FSDK_Version
    {
        /// <summary>
        /// 代码库版本号
        /// </summary>
        public int lCodebase;
        /// <summary>
        /// 主版本号
        /// </summary>
        public int lMajor;
        /// <summary>
        /// 次版本号
        /// </summary>
        public int lMinor;
        /// <summary>
        /// 编译版本号，递增
        /// </summary>
        public int lBuild;
        /// <summary>
        /// 字符串形式的版本号
        /// </summary>
        public IntPtr Version;
        /// <summary>
        /// 编译时间
        /// </summary>
        public IntPtr BuildDate;
        /// <summary>
        /// 版权信息
        /// </summary>
        public IntPtr CopyRight;
    }
}
